package xyz.lisys.compile;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import java.io.IOException;
import java.io.Writer;
import java.util.LinkedHashSet;
import java.util.Set;

@SupportedAnnotationTypes("xyz.lisys.annotation.AutoGenerate")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class AutoGenerateProcessor extends AbstractProcessor {

    // @Override
    // public Set<String> getSupportedAnnotationTypes() {
    //     Set<String> annotations = new LinkedHashSet<>();
    //     // 把我们自己定义的注解添加进去
    //     annotations.add(AutoGenerate.class.getCanonicalName());
    //     return annotations;
    // }
    //
    // @Override
    // public SourceVersion getSupportedSourceVersion() {
    //     return SourceVersion.latestSupported();
    // }

    @Override
    public synchronized void init(javax.annotation.processing.ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        // META-INF/services 目录下创建一个文件，文件名为 javax.annotation.processing.Processor
        // 在文件中指定你的注解处理器的全限定类名 xyz.lisys.annotation.AutoGenerateProcessor
        // 不要与主程序一起打包，需要单独打包引入
        for (Element element : roundEnv.getElementsAnnotatedWith(AutoGenerate.class)) {
            TypeElement typeElement = (TypeElement) element;
            String className = typeElement.getQualifiedName().toString();

            // 生成代码的逻辑
            generateCode(typeElement, className);
        }
        return true;
    }

    private void generateCode(TypeElement typeElement, String className) {
        // 示例：生成一个简单的 getter 方法
        String packageName = processingEnv.getElementUtils().getPackageOf(typeElement).getQualifiedName().toString();
        String getterMethodName = "getExample";
        String fieldName = "exampleField";
        String fieldType = "String";

        StringBuilder code = new StringBuilder();
        code.append("package ").append(packageName).append(";\n\n");
        code.append("public class ").append(className).append("Generated {\n");
        code.append("    public ").append(fieldType).append(" ").append(getterMethodName).append("() {\n");
        code.append("        return ").append(fieldName).append(";\n");
        code.append("    }\n");
        code.append("}\n");

        try {
            JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(packageName + "." + className + "Generated");
            try (Writer writer = sourceFile.openWriter()) {
                writer.write(code.toString());
            }
        } catch (IOException e) {
            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Error writing generated file");
        }
    }
}
